package com.zhss.dfs.namenode.server;

import java.util.LinkedList;
import java.util.List;

/**
 * 负责管理内存中的文件目录树的核心组件
 *
 * @author zhonghuashishan
 */
public class FSDirectory {

    /**
     * 内存中的文件目录树
     */
    private INode dirTree;

    public FSDirectory() {
        this.dirTree = new INode("/");
    }

    /**
     * 创建目录
     *
     * @param path 目录路径
     */
    public void mkdir(String path) {
        // path = /usr/warehouse/hive
        // 你应该先判断一下，“/”根目录下有没有一个“usr”目录的存在
        // 如果说有的话，那么再判断一下，“/usr”目录下，有没有一个“/warehouse”目录的存在
        // 如果说没有，那么就得先创建一个“/warehosue”对应的目录，挂在“/usr”目录下
        // 接着再对“/hive”这个目录创建一个节点挂载上去

        synchronized (dirTree) {
            String[] pathes = path.split("/");
            INode parent = dirTree;

            for (String splitedPath : pathes) {
                if (splitedPath.trim().equals("")) {
                    continue;
                }

                INode dir = findDirectory(parent, splitedPath);
                if (dir != null) {
                    parent = dir;
                    continue;
                }

                INode child = new INode(splitedPath);
                parent.addChild(child);
                parent = child;
            }
        }
    }

    /**
     * 查找子目录
     *
     * @param dir
     * @param path
     * @return
     */
    private INode findDirectory(INode dir, String path) {
        if (dir.getChildren().size() == 0) {
            return null;
        }

        INode resultDir;

        for (INode child : dir.getChildren()) {
            if (child instanceof INode) {
                INode childDir = (INode) child;

                if ((childDir.getPath().equals(path))) {
                    return childDir;
                }

//                resultDir = findDirectory(childDir, path);
//                if (resultDir != null) {
//                    return resultDir;
//                }
            }
        }

        return null;
    }




    /**
     * 代表文件目录树中的一个目录
     *
     * @author zhonghuashishan
     */
    public static class INode {

        private String path;
        private List<INode> children;

        public INode(String path) {
            this.path = path;
            this.children = new LinkedList<INode>();
        }

        public void addChild(INode inode) {
            this.children.add(inode);
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public List<INode> getChildren() {
            return children;
        }

        public void setChildren(List<INode> children) {
            this.children = children;
        }

        @Override
        public String toString() {
            return "INodeDirectory{" +
                    "path='" + path + '\'' +
                    ", children=" + children +
                    '}';
        }
    }



    @Override
    public String toString() {
        return "FSDirectory{" +
                "dirTree=" + dirTree +
                '}';
    }


    public void printDirTree(INode dir, int live) {
        if (dir.getChildren() == null || dir.getChildren().size() <= 0) {
            return;
        }
        for (INode child : dir.getChildren()) {
            for (int i = 0; i < live; i++) {
                System.out.print("  ");
            }
            System.out.println("/" + ((INode) child).getPath());
            printDirTree((INode)child, live + 1);
        }
    }
}
